package grape.attend.rest.user.mvc;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import grape.attend.rest.classe.mapper.ClasseWebMapper;
import grape.attend.rest.group.mapper.GroupWebMapper;
import grape.attend.rest.group.vo.GroupAndClasseClockVo;
import grape.attend.rest.user.form.UserClockOffClockForm;
import grape.attend.rest.user.mapper.UserClockDateClasseWebMapper;
import grape.attend.rest.user.mapper.UserClockDateWebMapper;
import grape.attend.rest.user.vo.UserClockDateClasseVo;
import grape.attend.rest.user.vo.UserClockDateVo;
import grape.attend.rest.user.vo.UserClockThreeMonthVo;
import grape.attend.service.classe.api.IClasseService;
import grape.attend.service.group.api.IGroupClasseRelService;
import grape.attend.service.group.api.IGroupService;
import grape.attend.service.user.api.IUserClockDateClasseService;
import grape.attend.service.user.api.IUserClockDateService;
import grape.attend.service.user.dto.GroupAndClasseDto;
import grape.attend.service.user.po.UserClockDate;
import grape.attend.service.user.po.UserClockDateClasse;
import grape.attend.service.user.query.UserClockDateListQuery;
import grape.attend.service.user.query.UserClockListQuery;
import grape.base.rest.client.dict.DictClient;
import grape.base.service.dict.api.IDictService;
import grape.base.service.dict.po.Dict;
import grape.common.exception.runtime.RBaseException;
import grape.common.rest.vo.NowVo;
import io.swagger.annotations.ApiParam;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.validation.Valid;
import grape.attend.rest.user.form.UserClockOnClockForm;
import grape.attend.rest.user.form.UserClockListPageForm;
import grape.attend.rest.user.vo.UserClockVo;
import grape.attend.rest.user.mapper.UserClockWebMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import grape.common.rest.mvc.BaseController;
import grape.attend.service.user.po.UserClock;
import grape.attend.service.user.api.IUserClockService;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * <p>
 * 用户打卡表 前端控制器
 * </p>
 *
 * @author yangwei
 * @since 2020-05-18
 */
@RestController
@RequestMapping("/attend/userclock")
@Api(tags = "用户打卡相关接口")
public class UserClockController extends BaseController<UserClockVo, UserClock> {

    @Autowired
    private UserClockWebMapper currentWebMapper;
    @Autowired
    private IUserClockService currentService;
    @Autowired
    private DictClient dictClient;
    @Autowired
    private IGroupClasseRelService iGroupClasseRelService;
    @Autowired
    private GroupWebMapper groupWebMapper;
    @Autowired
    private ClasseWebMapper classeWebMapper;
    @Autowired
    private IUserClockDateService iUserClockDateService;

    @Autowired
    private UserClockDateWebMapper userClockDateWebMapper;
    @Autowired
    private IUserClockDateClasseService iUserClockDateClasseService;
    @Autowired
    private UserClockDateClasseWebMapper userClockDateClasseWebMapper;
    @Autowired
    private IGroupService iGroupService;
    @Autowired
    private IClasseService iClasseService;


     @ApiOperation("上班打卡")
     @PreAuthorize("hasAuthority('userclock:single:onClock')")
     @PostMapping("onClock")
     @ResponseStatus(HttpStatus.CREATED)
     public UserClockVo onClock(@RequestBody @Valid UserClockOnClockForm cf,@ApiIgnore String loginUserId) {
         UserClock po = currentWebMapper.formToPo(cf);
         Dict dict = dictClient.getDictByCode(cf.getOnClockTypeDictCode());
         if (dict == null) {
             throw new RBaseException("字典编码不存在");
         }
         po.setOnClockTypeDictId(dict.getId());
         UserClock userClock = currentService.onClock(po,cf.getIsClasseYestoday(),loginUserId);
         return super.returnCreate(userClock);
     }
    @ApiOperation("下班打卡")
    @PreAuthorize("hasAuthority('userclock:single:offClock')")
    @PostMapping("offClock")
    @ResponseStatus(HttpStatus.CREATED)
    public UserClockVo offClock(@RequestBody @Valid UserClockOffClockForm cf, @ApiIgnore String loginUserId) {
        UserClock po = currentWebMapper.formToPo(cf);
        Dict dict = dictClient.getDictByCode(cf.getOffClockTypeDictCode());
        if (dict == null) {
            throw new RBaseException("字典编码不存在");
        }
        po.setOffClockTypeDictId(dict.getId());
        UserClock userClock = currentService.offClock(po,cf.getIsClasseYestoday(),loginUserId);
        return super.returnCreate(userClock);
    }

    @ApiOperation("分页查询用户打卡")
    @PreAuthorize("hasAuthority('userclock:single:listPage')")
    @GetMapping("/listPage")
    @ResponseStatus(HttpStatus.OK)
    public IPage<UserClockVo> listPage(UserClockListPageForm listPageForm) {
         UserClock po = currentWebMapper.formToPo(listPageForm);
         return super.listPage(po,listPageForm);
     }
     
    @ApiOperation("查询当前用户给定时间所在月份前后三个月的用户打卡")
    @PreAuthorize("hasAuthority('userclock:single:threeMonth')")
    @GetMapping("/threeMonth")
    @ResponseStatus(HttpStatus.OK)
    public UserClockThreeMonthVo threeMonth(@ApiParam("选择月份的时间戳") long current, @ApiIgnore String loginUserId) {
         
        // 当前月时间
        DateTime currentMonthDate = DateUtil.date(current);
        // 上一个月时间
        DateTime preMonthDate = DateUtil.offsetMonth(currentMonthDate, -1);
        // 下一个月时间
        DateTime nextMonthDate = DateUtil.offsetMonth(currentMonthDate, 1);

        // 响应结果
        UserClockThreeMonthVo userClockThreeMonthVo = new UserClockThreeMonthVo();

        List<DateTime> threeMonths = newArrayList(preMonthDate, currentMonthDate, nextMonthDate);
        
        List<UserClockDate> userClockDates = null;
        List<UserClock> userClocks = null;
        DateTime monthDate = null;
        List<GroupAndClasseClockVo> groupAndClasseClocks = null;
        UserClockDateVo itemUserClockDateVo = null;
        String classeDate = null;
        GroupAndClasseClockVo groupAndClasseClockVo = null;
        List<UserClockDateVo> userClockDateVos = null;
        List<UserClockDateClasse> userClockDateClasses = null;
        UserClockDateClasseVo userClockDateClasseVo = null;

        UserClockDateListQuery userClockDateListQuery = new UserClockDateListQuery();
        // 用户所有的班次
        List<GroupAndClasseDto> groupAndClasseCurrentByUserId = iGroupClasseRelService.getGroupAndClasseCurrentByUserId(loginUserId);
        for (int i = 0; i < threeMonths.size(); i++) {
            monthDate = threeMonths.get(i);
            userClockDateListQuery.setClasseDateStart(DateUtil.beginOfMonth(monthDate).toDateStr());
            userClockDateListQuery.setClasseDateEnd(DateUtil.endOfMonth(monthDate).toDateStr());
            userClockDates = iUserClockDateService.list(userClockDateListQuery);
            
            userClockDateVos = new ArrayList<>();
            if (!isEmpty(userClockDates)) {
                for (UserClockDate userClockDate : userClockDates) {
                    itemUserClockDateVo = userClockDateWebMapper.poToVo(userClockDate);
                    // 用户的打卡
                    userClocks = currentService.getByUserClockDateId(userClockDate.getId());
                    if (!isEmpty(userClocks)) {
                        itemUserClockDateVo.setUserClocks(posToVos(userClocks));
                    }

                    // 班次日期的班次
                    userClockDateClasses = iUserClockDateClasseService.getByUserClockDateId(userClockDate.getId());
                    if (!isEmpty(userClockDateClasses)) {
                        itemUserClockDateVo.setUserClockDateClasses(new ArrayList<>(userClockDateClasses.size()));
                        for (UserClockDateClasse userClockDateClass : userClockDateClasses) {
                            userClockDateClasseVo = userClockDateClasseWebMapper.poToVo(userClockDateClass);
                            userClockDateClasseVo.setGroup(groupWebMapper.poToVo(iGroupService.getById(userClockDateClass.getGroupId())));
                            userClockDateClasseVo.setClasse(classeWebMapper.poToVo(iClasseService.getById(userClockDateClass.getClasseId())));
                            itemUserClockDateVo.getUserClockDateClasses().add(userClockDateClasseVo);
                        }

                    }

                    userClockDateVos.add(itemUserClockDateVo);
                }
            }

            switch (i){
                // 上一个月
                case 0:{
                    userClockThreeMonthVo.setPreMonth(userClockDateVos);
                    break;
                }
                // 当前月
                case 1:{
                    userClockThreeMonthVo.setCurrentMonth(userClockDateVos);
                    break;
                }
                // 下一个月
                case 2:{
                    userClockThreeMonthVo.setNextMonth(userClockDateVos);
                    break;
                }
            }
        }

        userClockThreeMonthVo.setNow(new NowVo());
        return userClockThreeMonthVo;
    }

}
